package com.capsulode.excel.header;


import com.capsulode.excel.conversion.Reader;
import com.capsulode.excel.conversion.Validator;
import com.capsulode.excel.exception.CellTypeNotExpectException;
import com.capsulode.excel.exception.ConversionFailException;
import com.capsulode.excel.exception.ReadingProcessFailedException;
import com.capsulode.excel.exception.ValidationFailedException;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.poi.ss.usermodel.Cell;


public class AnnotatedHeader<R, F> extends AbstractHeader<R, F> {

    private final String fieldName;
    private final Class<F> fieldType;
    private final Reader<F> reader;
    private final Validator<F> validator;

    public AnnotatedHeader(String name, String fieldName, Class<F> fieldType, Reader<F> reader, Validator<F> validator, int columnIndex) {
        super(name);
        this.fieldName = fieldName;
        this.fieldType = fieldType;
        this.reader = reader;
        this.validator = validator;
        if (columnIndex >= 0) {
            setIndex(columnIndex);
        }
    }

    @Override
    protected void read(F f, R row) throws ReadingProcessFailedException {
        if (f == null) {
            return;
        }
        try {
            BeanUtils.copyProperty(row, fieldName, f);
        } catch (ReflectiveOperationException ex) {
            throw new ReadingProcessFailedException(ex);
        }
    }

    @Override
    protected void validate(F f) throws ValidationFailedException {
        if (validator != null) {
            validator.validate(f);
        }
    }

    @Override
    protected Class<F> type() {
        return fieldType;
    }

    @Override
    protected F convert(Cell cell, Class<F> type) throws ConversionFailException, CellTypeNotExpectException {
        return reader.convert(cell);
    }
}
